package com.sc.nft.admin.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.admin.request.*;
import com.sc.nft.admin.vo.ShareProfitPanelSimpleVO;
import com.sc.nft.admin.vo.ShareProfitPanelVO;
import com.sc.nft.annotation.SysMemberLogin;
import com.sc.nft.dao.*;
import com.sc.nft.dto.profit.SaveSharePoolDTO;
import com.sc.nft.dto.profit.SaveShareProfitDTO;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.AccessToCopyrightCollectioDTO;
import com.sc.nft.entity.dto.CollectionListAccordingDaoDTO;
import com.sc.nft.entity.dto.chain.TransferLogDTO;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.*;
import com.sc.nft.service.*;
import com.sc.nft.sup.PageRequest;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/profit")
@Api(tags = "后台分润模块")
public class ShareProfitAdminController {

    private final ShareProfitService shareProfitService;
    private final DaoShareConfigService daoShareConfigService;
    private final ShareProfitPanelService shareProfitPanelService;
    private final DigitalCollectionProductInfoDao digitalCollectionProductInfoDao;
    private final SecondCollectionConfigDao secondCollectionConfigDao;
    private final DigitalCollectionDao digitalCollectionDao;

    @ApiOperation(value = "交易池分润模版", notes = "交易池分润模版", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/listTransPoolProfit", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<List<ShareProfitPanel>> listTransPoolProfit() {
        return Result.success(shareProfitPanelService.listTransPoolProfit());
    }

    @ApiOperation(value = "分润模板列表", notes = "分润模板列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/page", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<ShareProfitPanelVO> saveProfit(@Valid @RequestBody ShareProfitPageRequest request) {
        return PageResult.success(shareProfitPanelService.panelPage(request.getPanelName(), request.getMarketLevel(), request.getStatus(), request.toMp()), ShareProfitPanelVO.class);
    }


    @ApiOperation(value = "保存分润配置", notes = "保存分润配置", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/saveProfit", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result saveProfit(@Valid @RequestBody SaveShareProfitDTO dto) {
        shareProfitService.saveProfit(dto);
        return Result.success();
    }

    @ApiOperation(value = "启用/禁用", notes = "保存分润配置", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/updateStatus", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result updateStatus(@Valid @RequestBody StatusRequest request) {
        ShareProfitPanel panel = shareProfitPanelService.getById(request.getId());
        if (!request.getStatus()) {
            switch (panel.getMarketLevel()) {
                case FIRST:
                    DigitalCollectionProductInfo productInfo = digitalCollectionProductInfoDao.getByPanelIdOne(panel.getId());
                    if (ObjectUtil.isNotNull(productInfo)) {
                        return Result.fail(StrUtil.format("商品{}已配置该模板，禁止下架", productInfo.getFirstTitle()));
                    }
                    break;
                case SECOND:
                    SecondCollectionConfig secondCollectionConfig = secondCollectionConfigDao.getByPanelIdOne(panel.getId());
                    if (ObjectUtil.isNotNull(secondCollectionConfig)) {
                        return Result.fail(StrUtil.format("藏品{}已配置该模板，禁止下架", digitalCollectionDao.getFirstTitleById(secondCollectionConfig.getCollectionId())));
                    }
                    break;
            }
        }
        panel.setStatus(request.getStatus());
        panel.updateById();
        return Result.success();
    }


    @ApiOperation(value = "获取分润配置", notes = "获取分润配置", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getProfit", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<SaveShareProfitDTO> getProfit(@Valid @RequestBody IdRequest request) {
        return Result.success(shareProfitService.getProfit(request.getId()));
    }


    @ApiOperation(value = "删除分润模板", notes = "删除分润模板", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/remove", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result remove(@Valid @RequestBody IdRequest request) {
        shareProfitPanelService.removePanel(request.getId());
        return Result.success();
    }


    @ApiOperation(value = "模板列表", notes = "模板列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/simpleList", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<List<ShareProfitPanelSimpleVO>> remove(@Valid @RequestBody MarketLevelRequest request) {
        return Result.successColl(shareProfitPanelService.findList(request.getPanelName(), request.getMarketLevel()), ShareProfitPanelSimpleVO.class);
    }

    @ApiOperation(value = "保存分红池", notes = "保存分红池", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/saveSharePool", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result saveSharePool(@Valid @RequestBody SaveSharePoolDTO dto) {
        daoShareConfigService.saveConfig(dto);
        return Result.success();
    }

    @ApiOperation(value = "分红池列表", notes = "分红池列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/sharePoolPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<DaoShareConfigVO> sharePoolPage(@Valid @RequestBody SharePoolPageRequest dto) {
        return PageResult.success(daoShareConfigService.getConfigPage(dto.getDaoId(), dto.getName(), dto.getStatus(), dto.toMp()));
    }

    @ApiOperation(value = "启用/禁用分红池", notes = "保存分红池", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/updatePoolStatus", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result saveSharePool(@Valid @RequestBody StatusRequest request) {
        DaoShareConfig config = daoShareConfigService.getById(request.getId());
        if (ObjectUtil.isEmpty(config)) {
            return Result.fail("未找到分润池");
        }
        if (request.getStatus()) {
            List<DaoShareConfig> openByDaoId = daoShareConfigService.getOpenByDaoId(config.getDaoId());
            BigDecimal first = openByDaoId.stream().map(DaoShareConfig::getFirstShareRatio).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
            BigDecimal second = openByDaoId.stream().map(DaoShareConfig::getSecondShareRatio).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
            if (NumberUtil.isGreater(first.add(config.getFirstShareRatio()), BigDecimal.ONE)) {
                return Result.fail("首发分润比例总和不得大于100%");
            }
            if (NumberUtil.isGreater(second.add(config.getSecondShareRatio()), BigDecimal.ONE)) {
                return Result.fail("手续费分润比例总和不得大于100%");
            }
        }
        config.setStatus(request.getStatus());
        config.updateById();
        return Result.success();
    }


}
